//
// Callback class for Sample Grabber filter.
//
class FrameGrabCallback : public ISampleGrabberCB
{
public :

 // Fake out any COM ref counting
    //
  STDMETHODIMP_(ULONG) AddRef() { return 2; }
  STDMETHODIMP_(ULONG) Release() { return 1; }
  STDMETHODIMP QueryInterface(REFIID iid, void** ppv)
  {
    if (NULL == ppv)
      return E_POINTER;
  
    *ppv = NULL;
    if (IID_IUnknown == iid)
    {
      *ppv = (IUnknown*)this;
      AddRef();
      return S_OK;
    }
    else 
    if (IID_ISampleGrabberCB == iid)
    {
      *ppv = (ISampleGrabberCB*)this;
      AddRef();
      return S_OK;
    }
  
    return E_NOINTERFACE;
  }
    
  // Constructor/destructor
  FrameGrabCallback() 
  {
	  framenum=0;
  }
    
  ~FrameGrabCallback() {}


public:
  // These will get set by the main thread below. We need to
  // know this in order to write out the bmp
  long Width;
  long Height;
  long framenum;
  CString strPath;

  STDMETHODIMP SampleCB(double n,IMediaSample *pms)
  {
	return 0;
  }


    // The sample grabber is calling us back on its deliver thread.
    // This is NOT the main app thread!
    //
    STDMETHODIMP BufferCB( double SampleTime, BYTE * pBuffer, long BufferSize )
    {
        //
        // Convert the buffer into a bitmap
        //
        TCHAR szFilename[MAX_PATH];
		if(strPath=="")
		{
			wsprintf(szFilename, TEXT("bitmap%ld.bmp\0"),  framenum );
		}
		else
		{
			wsprintf(szFilename, strPath ,  framenum );
		}
		
        
        framenum++;
        // Create a file to hold the bitmap
        HANDLE hf = CreateFile(szFilename, GENERIC_WRITE, FILE_SHARE_READ, 
                               NULL, CREATE_ALWAYS, NULL, NULL );

        if( hf == INVALID_HANDLE_VALUE )
        {
            _tprintf( TEXT("INVALID_HANDLE_VALUE\r\n"));
        }

        /*_tprintf(TEXT("Found a sample at time %ld ms\t[%s]\r\n"), 
                 long(SampleTime*1000), szFilename );*/

        // Write out the file header
        //
        BITMAPFILEHEADER bfh;
        memset( &bfh, 0, sizeof( bfh ) );
        bfh.bfType = 'MB';
        bfh.bfSize = sizeof( bfh ) + BufferSize + sizeof( BITMAPINFOHEADER );
        bfh.bfOffBits = sizeof( BITMAPINFOHEADER ) + sizeof( BITMAPFILEHEADER );

        DWORD Written = 0;
        WriteFile( hf, &bfh, sizeof( bfh ), &Written, NULL );

        // Write the bitmap format
        //
        BITMAPINFOHEADER bih;
        memset( &bih, 0, sizeof( bih ) );
        bih.biSize = sizeof( bih );
        bih.biWidth = Width;
        bih.biHeight = Height;
        bih.biPlanes = 1;
        bih.biBitCount = 24;

        Written = 0;
        WriteFile( hf, &bih, sizeof( bih ), &Written, NULL );

        // Write the bitmap bits
        //
        Written = 0;
        WriteFile( hf, pBuffer, BufferSize, &Written, NULL );

        CloseHandle( hf );

        return 0;
    }

};
